#-----------------------------------------------------------------------------
# Name:         utilities.Environment
# Purpose:     Sets up the user Environment
#
# Author:      Thomas Morton
#
# Created:     03/05/2008
# Copyright:   (c) 2008 Thomas Morton
#-----------------------------------------------------------------------------

'''

Sets up the user environment for ES IDE and sots out the data storage paths etc.

This is more of a module in itself than a utilitiy..

'''

# import the core modules
import os, random, string
# import 3rd party modules
from third_party import configobj,path,md5crypt
# assign the modules we need (makes the code easier to read)
ConfigObj = configobj.ConfigObj
crypt = md5crypt.md5crypt

# vars
debuglvl=None

# some default directories
root = path.path(os.getcwd())
userdata = root / "userdata"
datapath = root / "data"

# load some data files
data = ConfigObj(datapath / "program.dat")

# User object
class _UserEnvironment(object):
    '''
        This class sets up and sorts out the current user environment
        Status codes:
            0 = user does not exist
            1 = exists but not logged in
            2 = exists and logged in
    '''
    def __init__(self,user):
        self.u_dir = userdata / user
        self.name = user
        self._attributes = {}
        # set the login status to 0 (non-existant)
        self.u_status = 0
        if self.u_dir.exists():
            # they seem to have a user directory - so update status
            self.u_status = 1
            # woo it exists so load them
            self._load()
        
    def _load(self):
        # load the user up
        # grab the INI with ConfigObj and merge it wirh self._attributes
        self._attributes = (ConfigObj((self.u_dir / "%s.ini" % self.name)))
        if self._attributes["password"] == "":
            self.u_status = 2
    def _save(self):
        self._attributes.write()
       
    def create(self,password=None):
        # check we dont exist...
        if self.u_status > 0: return False
        # make the directory
        if not self.u_dir.exists():
            self.u_dir.mkdir(1)
        # path to the userfile
        ufile = self.u_dir / ("%s.ini" % self.name)
        # load the default cfg file
        temp = ConfigObj(userdata / "default/default.ini")
        # reset the filename
        temp.filename = ufile
        # are we setting a password
        if password:
            temp["password"] = crypt(password,_user_salt())
        # write the data out
        temp.write()
        # reload them
        self._load()
        # set the status as "exists"
        self.u_status = 1
        # return True so we know it worked
        return True
        
    def status(self):
        # does the user exist?? Check the status...
        return self.u_status
        
    def login(self,password):
        '''
            Attempts to login the user. Returns True if successful, False if not.
        '''
        # they mnust exist to try and log in
        if self.status == 0: return False
        # grab the salt and test password
        salt = self._attributes["password"][3:5]
        testpass = self._attributes["password"]
        # crypt the password we want to test
        # note: must prepend the salt.. :(
        password = crypt(password,salt)
        # is it correct?
        if password == testpass: 
            # set them as logged in and return
            self.u_status = 2
            return True
        return False

    def default(self):
        # toggle this user as the startup user
        data["UserEnv"]["startup"] = self.name
        
class _ProgramEnvironment(object):
    def __init__(self):
        # init the program
        datafile = datapath / "program.dat"
        if datafile.exists():
            self.status = 1
            # carry on
            pass
        else:
            # damn.. must install!
            self.status = 0
            
        
#
#       Private Methods
# 
        
def _user_salt(chars = string.letters + string.digits):
    # generate a random 2-character 'salt'
    return random.choice(chars) + random.choice(chars)
 
#
#       Public Methods
# 

def user(name,password=None):
    # grab a user instance
    temp = _UserEnvironment(name)
    # are we trying to verify the user as well?
    if password and temp.status() > 0:
        # try and log them in
        if temp.login(password):
            return temp
        # else return false - as we were tryign to log them in
        return False
    # ok so no passwd so we just want a user object..
    return temp
     
def list_users():
    temp = []
    for dir in userdata.dirs():
        if dir not in [".svn","default"]:
            temp.append(dir)
    return temp
    
def startup_user():
    '''
        Returns the name of the default user (ie
    '''
    if data["UserEnv"]["startup"] == "": return None
    return data["UserEnv"]["startup"]
    
 # the program environment only inits once!   
this = _ProgramEnvironment()
